TechNote - Favorites

Tuesday, June 16, 2026

10:41 AM

OneNote favorites are just like favorites in your Web browser: you save a page as a favorite, and then get to navigate back to that page at a later time by clicking that favorite.

 

Along the way, users have requested new features, including:

 

  • Can be organized in folders
  • Can be given a friendly name (alias)
  • Can be saved with a key sequence
  • Can be managed from the Favorites dialog (add, delete, organize, validate)
  • Can be exported/imported across machines

 

Why Move to a Database?

In the initial implementation it was designed to store each favorite as a bit of Ribbon XML - very convenient, but ultimately fragile and limiting. There was always the lingering concern that the XML-based file was too tightly reliant on the OneNote ribbon schema, conflating data with metadata, muddying model-view-controller overlap, and could break with any new release of OneNote. So moving the data to a real storage model and abstracting the view-controller pieces was always a long-term goal.

 

The requirement to organize into folders became the real tipping point to move favorites into the OneMore.db database, expanding its responsibility along with hashtags and table variables.

 

To maintain simplicity in both design and use, folders are limited to root folders only. The Favorites ribbon drop-down menu can contain a list of favorites and a list of folders, and those folders can have only a list of favorites themselves. No folders of folders.

 

Friendly Names

OneNote does not prevent creating two pages with the same name in a single section. To avoid the confusion, users are allowed to give friendly names to each favorite. The friendly name (alias) defaults to the actual page name until explicitly overridden.

 

Migration

If a Favorites.xml files exists, OneMore migrates this immediately upon the first use of Favorites. Uses include: expanding the Favorites drop-down menu, opening the Favorites dialog, opening the Settings/Favorites sheet, and of course, adding the current page to the Favorites list.

 

Once migrated, all subsequent uses will then only use the database.

 

Database Schema

These simple table definitions mirror the model classes in Commands\Favorites\Favorites.cs.

 

CREATE TABLE IF NOT EXISTS favorites_folder (
    folderID 
INTEGER PRIMARY KEY AUTOINCREMENT,
   
name      TEXT NOT NULL,
   
UNIQUE(name)
);

 

CREATE TABLE IF NOT EXISTS favorite (
    favoriteID 
INTEGER PRIMARY KEY AUTOINCREMENT,
    folderID   
INTEGER REFERENCES favorites_folder(folderID) ON DELETE CASCADE,
   
name        TEXT NOT NULL,
    alias      
TEXT,

    location    TEXT,

    uri         TEXT NOT NULL,

    notebookID  TEXT NOT NULL,

    sectionID   TEXT,

    pageID      TEXT,

    sortOrder   INTEGER NOT NULL DEFAULT 0

);

 

CREATE INDEX IF NOT EXISTS idx_favorites_folder ON Favorite(folderID);

 

-- Enforce that within a folder, each alias is unique. This allows us to use the alias as a
-- stable identifier for the favorite within the folder, even if the name or other properties
-- change. We only enforce this uniqueness when both folderID and alias are not null, allowing
-- for favorites without an alias or folder.

 

CREATE UNIQUE INDEX IF NOT EXISTS idx_favorite_alias_per_folder
   
ON Favorite(folderID, alias)
 
WHERE folderID IS NOT NULL AND alias IS NOT NULL;

 

-- Enforce that across all favorites without a folder, each alias is unique. This allows us to
-- use the alias as a stable identifier for the favorite, even if the name or other properties
-- change. We only enforce this uniqueness when the alias is not null.

 

CREATE UNIQUE INDEX IF NOT EXISTS idx_favorite_alias_root
   
ON Favorite(alias)
 
WHERE folderID IS NULL AND alias IS NOT NULL;

 

-- Enforce uniqueness for individual favorites, whether it targets a page, section,

-- or section group

 

CREATE UNIQUE INDEX IF NOT EXISTS idx_favorite_target_page

    ON favorite(pageID)

 WHERE pageID IS NOT NULL;

 

CREATE UNIQUE INDEX IF NOT EXISTS idx_favorite_target_section

    ON favorite(sectionID)

 WHERE pageID IS NULL;

 

 

#omwiki #omdeveloper #omtechnote

 

© 2020 Steven M Cohn. All rights reserved.

Please consider a sponsorship or one-time donation to support ongoing development

 

 

Created with OneNote.